package cn.rkylin.core.controller;

import cn.rkylin.apollo.common.util.BeanToMapUtil;
import cn.rkylin.apollo.utils.ExportExcelFileUtil;
import cn.rkylin.apollo.utils.ExportExcelSheet;
import cn.rkylin.core.ApolloMap;
import cn.rkylin.core.ApolloUtil;
import cn.rkylin.core.SessionFactory;
import cn.rkylin.core.service.ApolloService;
import cn.rkylin.core.utils.LogUtils;
import cn.rkylin.oms.common.context.WebContextFactory;
import cn.rkylin.oms.common.export.IExport;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.Configuration;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/core")
public class ApolloController extends AbstractController implements InitializingBean {
    protected static final String RECORDS_TOTAL = "recordsTotal";
    protected static final String RECORDS_FILTERED = "recordsFiltered";
    protected static final String RETURN_DATA = "data";
    protected static final String JSON_MSG = "msg";
    protected static final String JSON_RESULT = "result";
    protected static final String FAILED = "failed";
    protected static final String SUCCESS = "success";
    protected static final String VALUE_NO = "n";
    protected static final String VALUE_YES = "y";
    private static Logger logger = Logger.getLogger(LogUtils.LOG_BOSS);
    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    private ApolloService commonService;
    // 提供导出功能的服务
    private IExport exportService;

    /**
     * 查询index数据(默认不支持分页)
     *
     * @param request
     * @return
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping("/getData")
    @ResponseBody
    public List getData(HttpServletRequest request) throws Exception {
        String uuid = (String) request.getAttribute("uuid");
        LogUtils.info(logger, uuid, "【进入CommonController的getData方法中】");
        Map<String, Object> params = this.getParamMap(request);
        LogUtils.info(logger, uuid, "【请求入参】：", "inputParam", params);
        List list = commonService.findForList(params);
        LogUtils.info(logger, uuid, "【出参】：", "outputParam", list);
        /*
         * //异常跳转 String s = null; s.charAt(1);
		 */
        return list;
    }

    /**
     * 查询分业数据 (pageSize,pageNo.index 必传)
     *
     * @param request
     * @return
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping("/getPage")
    @ResponseBody
    public Map getPage(@RequestParam(required = false, defaultValue = "1") int page,
                       @RequestParam(required = false, defaultValue = "20") int rows, HttpServletRequest request)
            throws Exception {
        Map<String, Object> params = this.getParamMap(request);
        return commonService.findByPage(page, rows, params);
    }

    public String getKeyName(Map<String, Object> params, String key) {
        String keyName = "";
        if (null != params.get("downFields") && !"".equals(params.get("downFields"))) {
            String downFields = params.get("downFields") + "";
            String[] downFieldsList = downFields.split("\\|");
            for (int i = 0; i < downFieldsList.length; i++) {
                String tempStr = downFieldsList[i];
                String[] tempStrList = tempStr.split("\\:");
                if (null != tempStrList && tempStrList.length > 0) {
                    if (key.equals(tempStrList[0])) {
                        keyName = tempStrList[1];
                        break;
                    } else {
                        keyName = tempStrList[0];
                    }
                }
            }
        }
        return keyName;
    }

    /**
     * 根据模块statement拼装该模块的order by子句内容（未仔细测试）
     *
     * @param sqlMapperNamespace 该sqlmap的命名空间
     * @param sqlMapperStatement sqlmapper文件中的statement。（任意指定一个有的即可）
     * @param replaceFieldsMap   由于展示需要，前台的字段名与数据库字段名的转换关系。
     * @return 排序语句
     * @throws Exception
     */
    protected String getOrderString(String sqlMapperNamespace, String sqlMapperStatement,
                                    Map<String, String> replaceFieldsMap) throws Exception {
        return getOrderString(sqlMapperNamespace, sqlMapperStatement,
                replaceFieldsMap, "BaseResultMap");
    }

    /**
     * 根据模块statement拼装该模块的order by子句内容（未仔细测试）
     *
     * @param sqlMapperNamespace 该sqlmap的命名空间
     * @param sqlMapperStatement sqlmapper文件中的statement。（任意指定一个有的即可）
     * @param replaceFieldsMap   由于展示需要，前台的字段名与数据库字段名的转换关系。
     * @return 排序语句
     * @throws Exception
     */
    protected String getOrderString(String sqlMapperNamespace, String sqlMapperStatement,
                                    Map<String, String> replaceFieldsMap, String mapName) throws Exception {
        StringBuffer returnValue = new StringBuffer();
        boolean orderFlag = true;

        HttpServletRequest request = WebContextFactory.getWebContext().getRequest();
        for (int i = 0; orderFlag; i++) {
            // 排序的列号
            String order = request.getParameter("order[" + i + "][column]");
            // 排序的顺序asc or desc
            String orderDir = request.getParameter("order[" + i + "][dir]");
            // 排序的列名
            String orderColumn = request.getParameter("columns[" + order + "][data]");

            if (StringUtils.isEmpty(order) || StringUtils.isEmpty(orderDir) || StringUtils.isEmpty(orderColumn)) {
                orderFlag = false;
            } else {
                // 处理转义字段
                if (replaceFieldsMap != null && replaceFieldsMap.size() > 0) {
                    for (String replaceItem : replaceFieldsMap.keySet()) {
                        if (orderColumn.equals(replaceItem)) {
                            orderColumn = replaceFieldsMap.get(orderColumn);
                        }
                    }
                }

                Configuration conf = sessionFactory.getSessionFactory(ApolloUtil.CONN_MAP.get(sqlMapperStatement))
                        .getConfiguration();
                // 取得Configuration ,获取到对应的resultMap
                ResultMap map = conf.getResultMap(sqlMapperNamespace + "." + mapName);
                List<ResultMapping> mapping = map.getResultMappings();
                for (ResultMapping mp : mapping) {
                    if (mp.getProperty().equals(orderColumn)) {
                        returnValue.append(mp.getColumn() + " " + orderDir + ",");
                        break;
                    }
                }
            }
        }
        int lastComma = returnValue.toString().lastIndexOf(",");
        if (lastComma < 0) {
            return "";
        } else {
            return returnValue.toString().substring(0, lastComma);
        }
    }

    protected IExport getExportService() {
        return exportService;
    }

    protected void setExportService(IExport exportService) {
        this.exportService = exportService;
    }

    /**
     * 具体controller根据情况重写此方法
     */
    @Override
    public void afterPropertiesSet() throws Exception {
    }

    /**
     * 验证需要导出的条件
     *
     * @param quickSearch 快速查询条件
     * @param colName     需要导出的项目名称
     * @param colValue    需要导出的项目的字段名称
     * @return 返回值JSON格式字符串
     */
    @ResponseBody
    @RequestMapping(value = "/exportCheck")
    public String exportShopCheck(String colName, String colValue) throws Exception {
        JSONObject returnJSON = new JSONObject();
        try {
            colName = URLDecoder.decode(colName, "UTF-8");
            colValue = URLDecoder.decode(colValue, "UTF-8");
            String[] colNameArry = colName.split(",");
            String[] colValueArry = colValue.split(",");
            if (exportService == null) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "系统错误");
            } else if (StringUtils.isBlank(colName) || StringUtils.isBlank(colValue)) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "请选择导出项目");
            } else if (colNameArry.length != colValueArry.length) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "选择导出项目有误");
            } else {
                returnJSON.put(JSON_RESULT, SUCCESS);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            returnJSON.put(JSON_RESULT, FAILED);
            returnJSON.put(JSON_MSG, ex.getMessage());
        }
        return JSONObject.toJSONString(returnJSON, SerializerFeature.WriteMapNullValue);
    }

    /**
     * 导出店铺ajax
     *
     * @param quickSearch 快速查询条件
     * @param colName     需要导出的项目名称
     * @param colValue    需要导出的项目的字段名称
     * @param response    导出文件的时候返回文件流用
     * @return 返回值JSON格式字符串
     */
    @RequestMapping(value = "/export")
    public void exportShopExcel(String quickSearch, String colName, String colValue, String exportStatement, HttpServletResponse response)
            throws Exception {
        try {
            ApolloMap<String, Object> params = new ApolloMap<String, Object>();
            params.put(ApolloUtil.INDEX_PARAM, exportStatement);
            quickSearch = URLDecoder.decode(quickSearch, "UTF-8");
            colName = URLDecoder.decode(colName, "UTF-8");
            colValue = URLDecoder.decode(colValue, "UTF-8");
            String[] colNameArry = colName.split(",");
            String[] colValueArry = colValue.split(",");

            if (StringUtils.isBlank(colName) || StringUtils.isBlank(colValue)) {
                return;
            }

            if (colNameArry.length != colValueArry.length) {
                return;
            }

            // 获取数据
            List<T> resultList = exportService.execExport(exportStatement, quickSearch);

            Workbook xs = new HSSFWorkbook();

            if (colNameArry != null && colNameArry.length > 0 && colValueArry != null && colValueArry.length > 0) {

                // 设置sheet内容
                ExportExcelSheet exportExcelSheet = new ExportExcelSheet();
                // 如果是VO的话需要转黄成为MAP形式 结果集set
                exportExcelSheet.setListRow(new BeanToMapUtil().convertListBean2ListMap(resultList));
                // 导出项目单元格的属性设置
                exportExcelSheet.setListTitle(colName, colValue);
                // 设置要导出的sheet
                Map<String, ExportExcelSheet> exportExcelMap = new HashMap<String, ExportExcelSheet>();
                // sheet页名称，以及对应的sheet内容
                exportExcelMap.put("sheet", exportExcelSheet);

                xs = ExportExcelFileUtil.exportData(exportExcelMap, "ExportList.xls");
            }
            OutputStream out = response.getOutputStream();
            String mimetype = "application/x-msdownload";
            response.setContentType(mimetype);
            String inlineType = "attachment"; // 是否内联附件
            response.setHeader("Content-Disposition", inlineType + ";filename=\"" + "ExportShopList.xls" + "\"");
            xs.write(out);
            out.flush();
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
